import { onMounted, onUnmounted, reactive, Ref, ref, watch } from 'vue'
import { Widget } from '@/models'
import { EffectLock } from '@/utils'

/** 控件多选 */
export default function useSelection(onChange?: (selected: Widget[]) => void) {
  /** 已选中列表 */
  const list: Ref<Widget[]> = ref([])

  /** 新增 */
  function add(...widgets: Widget[]) {
    const selected = list.value

    widgets.forEach(widget => {
      if (!widget.isRiding && !widget.isFixed && !selected.includes(widget)) {
        selected.push(widget)
      }
    })
  }

  /** 移除 */
  function remove(...widgets: Widget[]) {
    const selected = list.value

    widgets.forEach(widget => selected.splice(selected.indexOf(widget), 1))
  }

  /** 清除 */
  function clear() {
    list.value = []
  }

  /** 清除锁定 */
  const lock = new EffectLock()

  watch([list, () => list.value.length], ([selected]) => {
    if (!selected.length) return

    onChange?.(selected)
  })

  function clearOutSide(e: MouseEvent) {
    // 锁定状态、Ctrl/Cmd 多选状态，无需清除
    if (lock.locked || e.ctrlKey || e.metaKey) return

    clear()
  }

  onMounted(() => document.addEventListener('click', clearOutSide))

  onUnmounted(() => document.removeEventListener('click', clearOutSide))

  return reactive({
    /** 已选中列表 */
    list,

    /** 新增 */
    add,

    /** 移除 */
    remove,

    /** 清除 */
    clear,

    /** 切换选择 */
    toggle(widget: Widget) {
      const selected = list.value
      const willAdd = !selected.includes(widget)

      willAdd ? add(widget) : remove(widget)

      return willAdd
    },

    /** 设置锁定，避免被清除 */
    lock: () => lock.lock()
  })
}
